package com.qida.clm.core.network.response;

import java.lang.reflect.Type;

import org.json.JSONException;
import org.json.JSONObject;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.qida.clm.core.network.MessageCode;
import com.qida.clm.core.network.NetworkHelp;
import com.qida.clm.core.network.ResponseBean;
import com.qida.clm.core.network.ResponseException;
import com.qida.clm.core.network.intercept.ErrorCodeProcessManager;
import com.qida.clm.core.network.request.IRequest;

/**
 * Created by xiexiang on 2015/10/16.
 */
public class BasicResponse<T> implements IResponse<T> {

    private ResponseBean<T> mResponseBean = new ResponseBean<T>();
    private ResponseCallback<T> mCallback;
    protected Gson mGson = new Gson();
    private IRequest<T> mRequest;
    protected Type mType;
    private ErrorCodeProcessManager mErrorCodeProcessManager;

    public BasicResponse(Type type,ResponseCallback<T> callback){
        this.mCallback = callback;
        this.mType = type;
        this.mErrorCodeProcessManager = ErrorCodeProcessManager.getInstance();
    }

    @Override
    public void processResponse(String result){
        //检查数据是否有效
        if(TextUtils.isEmpty(result) || !result.startsWith("{")){
            mResponseBean.setExecuteStatus(MessageCode.FAIL);
            mResponseBean.setErrorMsg("Invalid data.");
            return;
        }
        try{
            JSONObject jsonObject = onParseRootData(result);
            if(mResponseBean.getExecuteStatus() == MessageCode.SUCCEED){
            	if(jsonObject.has("values")){
                	String values = jsonObject.getString("values");
                	T value = onParseValueData(values);
                	if(value == null){
                		value = mGson.fromJson(values, mType);
                	}
                	onParseValueFinish(value);
                    mResponseBean.setValues(value);            		
            	}
            }
        } catch (JSONException e){
            mResponseBean.setExecuteStatus(MessageCode.FAIL);
            mResponseBean.setErrorMsg("JSON resolve fail:"+e.getMessage());
        } catch (Exception e) {
            mResponseBean.setExecuteStatus(MessageCode.FAIL);
            mResponseBean.setErrorMsg(e.getMessage());
        } finally{
        	NetworkHelp.getInstance().postResponse(new Runnable() {
    			@Override
    			public void run() {
    				onProcessFinish();
    			}
    		});
        }
    }

    protected void onParseValueFinish(T values){}

    /**
     * 解析根节点
     * @param json
     * @return
     * @throws JSONException
     */
    protected JSONObject onParseRootData(String json)throws JSONException{
        JSONObject rootJson = new JSONObject(json);
        int executeStatus = rootJson.getInt("executeStatus");
        if(executeStatus == 0){
            //Server return succeed.
            mResponseBean.setExecuteStatus(MessageCode.SUCCEED);
        } else {
            mResponseBean.setExecuteStatus(MessageCode.SERVER_ERROR_FAIL);
            if(rootJson.has("errorCode")){
                mResponseBean.setErrorCode(rootJson.getInt("errorCode"));
            }
            if(rootJson.has("errorMsg")){
                mResponseBean.setErrorMsg(rootJson.getString("errorMsg"));
            }
        }
        return rootJson;
    }

    /**
     * 解析value json
     * @param valueJson
     * @throws JSONException
     */
    protected T onParseValueData(String valueJson)throws JSONException{
    	return null;
    }

    @Override
    public int getStatusCode() {
        return mResponseBean.getErrorCode();
    }

    @Override
    public String getErrorMessage() {
        return mResponseBean.getErrorMsg();
    }

    @Override
    public int getExecuteStatus() {
        return mResponseBean.getExecuteStatus();
    }

    @Override
    public T getValues() {
        return mResponseBean.getValues();
    }

    @Override
    public void setRequest(IRequest<T> request) {
        this.mRequest = request;
    }

    @Override
    public ResponseCallback<T> getCallBack() {
        return mCallback;
    }

    /**
     * 处理完成
     */
    private void onProcessFinish(){
    	//服务器返回的数据是错误的,有错误就直接返回,直接执行onFailure方法.
    	if(mResponseBean.getExecuteStatus() == MessageCode.SERVER_ERROR_FAIL){
    		int errorCode = mResponseBean.getErrorCode();
    		if(!mErrorCodeProcessManager.processErrorCode(errorCode)){
                onFailureCallback(errorCode,mResponseBean.getErrorMsg());
    		}
    		return;
    	}
        onSuccessCallback();
    }

    private void onSuccessCallback(){
        if(mCallback != null){
            mCallback.onRequestFinish();
            mCallback.onSuccess(getValues());
        }
    }

    private void onFailureCallback(int errorCode,String errorMessage){
        if(mCallback != null){
            mCallback.onRequestFinish();
            mCallback.onFailure(errorCode,errorMessage);
        }
    }

	@Override
	public void processError(ResponseException error) {
		if(error != null){
            onFailureCallback(error.getErrorCode(), error.getMessage());
		}
	}

    @Override
    public void processCache(T cache) {
        if(mCallback != null){
            mCallback.onRequestFinish();
            mCallback.onSuccess(cache);
        }
    }
}